package com.zhihuishu.micro.course.service.impl;

import com.zhihuishu.micro.course.constant.CourseSpeakerConstant;
import com.zhihuishu.micro.course.dao.CourseSpeakerMapper;
import com.zhihuishu.micro.course.dto.CourseSpeakerDto;
import com.zhihuishu.micro.course.helper.RedisKeyHelper;
import com.zhihuishu.micro.course.model.CourseSpeaker;
import com.zhihuishu.micro.course.service.CourseSpeakerService;
import com.zhihuishu.toolkit.helper.BeanHelper;
import com.zhihuishu.toolkit.jedis.JedisHelper.Handler;
import com.zhihuishu.toolkit.jedis.template.JedisExecutor;

import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;

import javax.annotation.Resource;

import java.util.*;
@Service("courseSpeakerService")
public class CourseSpeakerServiceImpl extends BaseService implements CourseSpeakerService {
	
	@Resource
	private CourseSpeakerMapper courseSpeakerMapper ;

	 @Resource
	 private JedisExecutor jedisExecutor;

	//@Override
	public boolean findCourseSpeakerIsNotEmpty(Long courseId, Integer type) {
		boolean flag = false;
		int count = courseSpeakerMapper.findCourseSpeakerCount(courseId, type);
		if(count>0){
			flag = true;
		}
		return flag;
	}
	/**
	 * 新增教师团队信息
	 * @author shehuaiyang
	 * @date 2016年9月18日 下午4:38:48
	 * @modifyNote
	 * @param csd
	 * @return
	 */
	@Override
	public CourseSpeakerDto insert(CourseSpeakerDto csd) {
		
		Assert.notNull(csd, "csd not must not null");
		
		CourseSpeaker cs = BeanHelper.transTo(csd, CourseSpeaker.class);
		courseSpeakerMapper.save(cs);

        //hash
        Integer generatedId = cs.getId();
        Assert.notNull(generatedId, "generatedId not must not null");
        this.setRedisCourseSpeakerData(generatedId);

        //id set
		List<String> keys = this.getRedisCourseSpeakers(cs.getCourseId());
        keys.add(String.valueOf(generatedId));
        this.setRedisSpeakerCourseIds(keys, cs.getCourseId());
		
		return BeanHelper.transTo(cs,CourseSpeakerDto.class);
	}
	/**
	 * 查询教师团队信息
	 * @author shehuaiyang
	 * @date 2016年9月18日 下午4:48:07
	 * @modifyNote
	 * @param courseId
	 * @return
	 */
	@Override
	public List<CourseSpeakerDto> searchCourseSpeakerList(long courseId) {
		
		Assert.notNull(courseId, "courseId not must not null");

        //query cache
		List<CourseSpeakerDto> csds = this.getRedisCourseSpeakersData(courseId);

		if (CollectionUtils.isEmpty(csds)) {
			//query db & setting cache
			return this.setRedisCourseSpeakers(courseId);
		}
		return csds;
	}
	
	/**
	 * 修改教师团队信息
	 * @author shehuaiyang
	 * @date 2016年9月18日 下午4:39:16
	 * @modifyNote
	 * @param csd
	 * @return
	 */
	@Override
	public CourseSpeakerDto update(CourseSpeakerDto csd) {				
	        Assert.notNull(csd, "对象信息不能为空");
		CourseSpeaker cs = BeanHelper.transTo(csd, CourseSpeaker.class);
		courseSpeakerMapper.update(cs);

        //del cache
		this.removeCache(cs.getId());

        //load from db & setting cache
		this.setRedisCourseSpeakerData(cs.getId());

		return BeanHelper.transTo(cs, CourseSpeakerDto.class);

	}
    /**
     * 逻辑删除教师团队信息
     * @author shehuaiyang
     * @date 2016年9月18日 下午4:39:36
     * @modifyNote
     * @param courseSpeakerId
     */
	@Override
	public void delete(Integer courseSpeakerId) {
		Assert.notNull(courseSpeakerId, "对象信息不能为空");
		CourseSpeakerDto dto = this.getRedisCourseSpeakerData(courseSpeakerId);
		
		if(courseSpeakerId != null){
            courseSpeakerMapper.delete(courseSpeakerId);
		}
		this.removeCache(courseSpeakerId);
		
		if(null != dto){
			this.removeFromRelationKeys(dto.getCourseId(),String.valueOf(courseSpeakerId));
		}
	}
    /**
     * 根据主键查询教师团队返回的条数
     * @author shehuaiyang
     * @date 2016年9月18日 下午4:39:58
     * @modifyNote
     * @param id
     * @return
     */
	@Override
	public int countCourseSpeaker(Integer id) {

	   Assert.notNull(id, "id must not null");
		int n = this.courseSpeakerMapper.countCourseSpeaker(id);
		return n;
	}
    /**
     * 根据id查询出相应的教师团队信息
     * @author shehuaiyang
     * @date 2016年9月18日 下午4:44:24
     * @modifyNote
     * @param id
     * @return
     */
	@Override
	public CourseSpeakerDto findCourseSpeakerById(Integer id) {
		
		Assert.notNull(id, "id must not be null");
		CourseSpeakerDto cd = this.getRedisCourseSpeakerData(id);
		if(null == cd){
			return this.setRedisCourseSpeakerData(id);
		}
		return cd;
	}
	/**
	 * 从DB中查询教师团队信息
	 * @Description
	 * @author shehuaiyang
	 * @date 2016年9月18日 下午4:45:22
	 * @modifyNote 
	 * @param id
	 * @return
	 */
	public CourseSpeakerDto loadCourseSpeakerById(Integer id){
	    Assert.notNull(id, "id must not null");
		CourseSpeaker csd = new CourseSpeaker();
		              csd =  courseSpeakerMapper.findCourseSpeaker(id);
		              
		return BeanHelper.transTo(csd,CourseSpeakerDto.class);
	}
	/**
	 * 根据课程id从DB中查询教师团队列表
	 * @Description
	 * @author shehuaiyang
	 * @date 2016年9月18日 下午4:45:46
	 * @modifyNote 
	 * @param courseId
	 * @return
	 */
	public List<CourseSpeakerDto> getCourseSpeakerList(Long courseId) {

		 List<CourseSpeaker> coursepeakers = courseSpeakerMapper.selectCourseSpeaker(courseId);
		   if(CollectionUtils.isEmpty(coursepeakers)){
			   return null;
		   }else{
				List<CourseSpeakerDto> courseSpeakerDtoList = new ArrayList<CourseSpeakerDto>();
				for(CourseSpeaker courseSpeaker : coursepeakers){
					if (courseSpeaker != null){					                  
						courseSpeakerDtoList.add(BeanHelper.transTo(courseSpeaker,CourseSpeakerDto.class));
					}
				}
				return courseSpeakerDtoList;
		}
	}
	/**
	 * 获取缓存redis中所有的教师团队信息
	 * @Description
	 * @author shehuaiyang
	 * @date 2016年9月18日 下午4:43:48
	 * @modifyNote 
	 * @param courseId
	 * @return
	 */
	public List<CourseSpeakerDto> getRedisCourseSpeakersData(final long courseId){
		
		List<CourseSpeakerDto> csds = new ArrayList<CourseSpeakerDto>();	
		List<String> ids = this.getRedisCourseSpeakers(courseId);
		if(CollectionUtils.isEmpty(ids)){
			return null;
		}
        for (String courseSpeakerId : ids) {
            CourseSpeakerDto cd = this.getRedisCourseSpeakerData(Integer.parseInt(courseSpeakerId));

            if(null == cd){
                continue;
            }
            csds.add(cd);
        }
		return csds;
	}
	
	/**
	 * 获取缓存中存放的相应课程id中的所有教师团队
	 * @Description
	 * @author shehuaiyang
	 * @date 2016年9月18日 下午4:43:16
	 * @modifyNote 
	 * @param courseId
	 * @return
	 */
	public List<String> getRedisCourseSpeakers(final long courseId){
        final List<String> ret = new LinkedList<String>();

        jedisExecutor.execute( new Handler(){

			@Override
			public void handle(Jedis jedis) {
				
				String key = RedisKeyHelper.getCourseSpeakerIdsKey(courseId);
				
				if(jedis.exists(key)){

                    Set<String> smembers = jedis.smembers(key);
                    ret.addAll(smembers);

				}
			}
			
		});
		return ret;
		
		
	}
	/**
	 * 将课程id相关的教师团队信息存放到redis中
	 * @Description
	 * @author shehuaiyang
	 * @date 2016年9月18日 下午4:42:11
	 * @modifyNote 
	 * @param courseId
	 * @return
	 */
	public List<CourseSpeakerDto> setRedisCourseSpeakers(final long courseId){

        //from DB
		List<CourseSpeakerDto> csds = this.getCourseSpeakerList(courseId);
		
		if(CollectionUtils.isEmpty(csds)){
			return null;
		}
		
		List<String> keys = new ArrayList<String>(csds.size());
		
		for(CourseSpeakerDto csd : csds){
			
			final Map<String, String> map = BeanHelper.describe(csd);
			final String key = RedisKeyHelper.getCourseSpeakerKey(csd.getId());
			jedisExecutor.execute( new Handler(){
				@Override
				public void handle(Jedis jedis) {
					
					jedis.hmset(key, map);
				}
				
			});
			
            keys.add(csd.getId().toString());
		}
		
		this.setRedisSpeakerCourseIds(keys, courseId);
		
		return csds;
	}
    /**
     * 将教师团队中的keys存到redis中
     * @Description
     * @author shehuaiyang
     * @date 2016年9月18日 下午4:40:46
     * @modifyNote 
     * @param keys
     * @param courseId
     */
	public void setRedisSpeakerCourseIds(final List<String> keys, final long courseId) {
		jedisExecutor.execute( new Handler(){

			@Override
			public void handle(Jedis jedis) {
                String key = RedisKeyHelper.getCourseSpeakerIdsKey(courseId);
                jedis.del(key);
                if (!CollectionUtils.isEmpty(keys)) {
                    jedis.sadd(key, keys.toArray(new String[keys.size()]));
                }
			}
			
		});
		
	}
 /**
  * 从redis缓存中获取教师团队中的对象
  * @Description
  * @author shehuaiyang
  * @date 2016年9月18日 下午4:37:44
  * @modifyNote 
  * @param courseSpeakerId
  * @return
  */
  public  CourseSpeakerDto getRedisCourseSpeakerData(final Integer courseSpeakerId) {
		
		final CourseSpeakerDto csd = new CourseSpeakerDto();
		jedisExecutor.execute( new Handler(){

			@Override
			public void handle(Jedis jedis) {
				 CourseSpeakerDto dto = null;
				 String key = RedisKeyHelper.getCourseSpeakerKey(courseSpeakerId);
				
				 if(jedis.exists(key)){
					 Map<String, String> map = jedis.hgetAll(key);
					 if(!CollectionUtils.isEmpty(map) && map.get("id") != null){
						 dto = BeanHelper.transTo(map, CourseSpeakerDto.class);
					 }
				 }
				 if(dto != null && dto.getId() !=null){
					 BeanHelper.copyProperties(dto, csd);
				 }
			}
			
		});
		return csd.getId() != null ? csd :null;
	}
    /**
     * 首先从DB查询教师团队的对象
     * 然后设置存到redis中
     * @Description
     * @author shehuaiyang
     * @date 2016年9月18日 下午4:36:51
     * @modifyNote 
     * @param id
     * @return
     */
	public  CourseSpeakerDto setRedisCourseSpeakerData(final Integer id) {
		
		 CourseSpeakerDto csd = this.loadCourseSpeakerById(id);
		 
		 if(null == csd){
			 return null;
		 }
		 final Map<String, String> map = BeanHelper.describe(csd);
		 
		 if(!CollectionUtils.isEmpty(map)){
			 jedisExecutor.execute( new Handler(){

				@Override
				public void handle(Jedis jedis) {
					jedis.hmset(RedisKeyHelper.getCourseSpeakerKey(id), map);
				}
				 
			 });
		 }
		return csd;
		 		
	}
	/**
	 * 删除教师团队所对应的建课主键
	 * @Description
	 * @author shehuaiyang
	 * @date 2016年9月18日 下午4:36:06
	 * @modifyNote 
	 * @param courseId
	 */
	private void removeCacheKeys(final long courseId) {
		jedisExecutor.execute( new Handler() {

			@Override
			public void handle(Jedis jedis) {
				jedis.del(RedisKeyHelper.getCourseSpeakerIdsKey(courseId));
			}

		});
	}
	private void removeFromRelationKeys(final long courseId,final String courseSpeakerId) {
		jedisExecutor.execute( new Handler() {

			@Override
			public void handle(Jedis jedis) {
//				jedis.del(RedisKeyHelper.getCourseSpeakerIdsKey(courseId));
                jedis.srem(RedisKeyHelper.getCourseSpeakerIdsKey(courseId),courseSpeakerId);
            }

		});
	}

	/**
	 * 删除教师团队的缓存id
	 * @Description
	 * @author shehuaiyang
	 * @date 2016年9月18日 下午4:35:19
	 * @modifyNote 
	 * @param id
	 */
	private void removeCache(final Integer id) {
		jedisExecutor.execute( new Handler() {
			@Override
			public void handle(Jedis jedis) {
				jedis.del(RedisKeyHelper.getCourseSpeakerKey(id));

			}

		});
	}
	
	@Override
	public List<Integer> findCourseSpeakerTypeList(Long courseId) {
		return courseSpeakerMapper.findCourseSpeakerTypeList(courseId);
	}
	@Override
	public Map<String, Boolean> findCourseSpeakerIsComplete(Long courseId,int type) {
		if( courseId == null){
			Assert.notNull(courseId, "courseId must not null");
			return null;
		}
		Map<String, Boolean> map = new HashMap<String, Boolean>();
		List<CourseSpeaker> coursepeakers = courseSpeakerMapper.selectCourseSpeaker(courseId);
		boolean planFlag = true ; //总策划是否完整
		boolean teamFlag = true ; //教学团队是否完整
		if(!CollectionUtils.isEmpty(coursepeakers)){
			int planCount = 0 ; // 0 表示总策划数据为空
			int teamCount = 0 ; // 0 表示教学团队为空
			for(CourseSpeaker model:coursepeakers){
				boolean flag = true;
				if(StringUtils.isEmpty(model.getUsername())){
					flag = false;
				}
				if(StringUtils.isEmpty(model.getJobstatus())){
					flag = false;
				}
				if(type == CourseSpeakerConstant.TYPE_4 && StringUtils.isEmpty(model.getImg())){
					flag = false;
				}
				if(StringUtils.isEmpty(model.getDecription())){
					flag = false;
				}
				if(flag == false){
					if(CourseSpeakerConstant.USER_TYPE_1.equals(model.getUserType()+"")){
						teamFlag = false;
					}
					if(CourseSpeakerConstant.USER_TYPE_2.equals(model.getUserType()+"")){
						planFlag = false;
					}
					if(type == CourseSpeakerConstant.TYPE_4){
						break;
					}
				}
				if(CourseSpeakerConstant.USER_TYPE_1.equals(model.getUserType()+"")){
					teamCount++ ;
				}
				if(CourseSpeakerConstant.USER_TYPE_2.equals(model.getUserType()+"")){
					planCount++ ;
				}
				
			}
			//教学团队没数据时（海外建课教学团队为null时，可算完整）
			if(type != CourseSpeakerConstant.TYPE_4 && teamCount == 0){
				teamFlag = false;
			}
			//总策划没数据时
			if(planCount == 0){
				planFlag = false;
			}
			map.put(CourseSpeakerConstant.TEAM, teamFlag);
			map.put(CourseSpeakerConstant.PLAN, planFlag);
			if(planFlag&&teamFlag){
				map.put(CourseSpeakerConstant.ALL, true);
			}else{
				map.put(CourseSpeakerConstant.ALL, false);
			}
		}else{
			map.put(CourseSpeakerConstant.PLAN, false);
			map.put(CourseSpeakerConstant.TEAM, false);
			map.put(CourseSpeakerConstant.ALL, false);
		}		
		return map;
	}

	@Override
	public void updateCourseSpeakerOrderNumber(final Map<String, Object> paramMap) {
		//修改数据库
		courseSpeakerMapper.updateCourseSpeakerOrderNumber(paramMap);
		//修改缓存
		jedisExecutor.execute( new Handler(){
			@Override
			public void handle(Jedis jedis) {
				jedis.hset(RedisKeyHelper.getCourseSpeakerKey(Integer.parseInt(paramMap.get("courseSpeakerId")+"")), "userType", paramMap.get("type")+"");
				jedis.hset(RedisKeyHelper.getCourseSpeakerKey(Integer.parseInt(paramMap.get("courseSpeakerId")+"")), "orderNumber", paramMap.get("orderNumber")+"");
			}
		 });
	}
	
	@Override
	public List<Integer> getAllCourseId() {
		return courseSpeakerMapper.getAllCourseId();
	}

	@Override
	public void setOrderNumebrForOldCourseSpeaker(Integer courseId, Integer userType) {
		courseSpeakerMapper.setOrderNumebrForOldCourseSpeaker(courseId, userType);
	}

	@Override
	public Integer getMaxOrderNumberByCourseIdAndUserType(Long courseId, Integer userType) {
		Integer maxOrderNumber = 0;
		// 先查缓存 
		List<CourseSpeakerDto> cacheList = this.searchCourseSpeakerList(courseId);
		if (cacheList != null && cacheList.size() > 0) {
			for (CourseSpeakerDto courseSpeakerDto : cacheList) {
				if (userType.equals(courseSpeakerDto.getUserType())) {
					if (courseSpeakerDto.getOrderNumber() != null && courseSpeakerDto.getOrderNumber() > maxOrderNumber) {
						maxOrderNumber = courseSpeakerDto.getOrderNumber();
					}
				}
			}
		}
		// 缓存无则查库
		if (maxOrderNumber == 0) {
			maxOrderNumber = courseSpeakerMapper.getMaxOrderNumberByCourseIdAndUserType(courseId, userType);
		}
		return maxOrderNumber == null ? 0 : maxOrderNumber;
	}

	@Override
	public List<Integer> getAllCourseSpeakerId() {
		return courseSpeakerMapper.getAllCourseSpeakerId();
	}

}
